var fs = require('fs');
var os = require('os');
var db = require('db');
var vm = require('vm');
var http = require('http');
var hash = require('hash');
var path = require("path");
var process = require('process');
var coroutine = require('coroutine');
coroutine.current().env = 'test';
var AsciiTable = require('asciitable');
var util = require('util');
require("./tools");


var casesPath = {
    defs: 'defs/',
};

global.check_result = function(res, data, filters = []) {
    function clen_result(res, filters) {
        if (util.isObject(res)) {
            if (Array.isArray(res))
                res.forEach(r => clen_result(r, filters));
            else {
                for (let k of filters)
                    delete res[k];

                for (var k in res)
                    clen_result(res[k], filters);
            }
        }
    }
    clen_result(res, filters);
    assert.deepEqual(res, data);
}

GC();
var no = os.memoryUsage().nativeObjects.objects;

var fn = {
    listCases: function(t, c) {
        function getCaseinfo(t, c) {
            return {
                name: c,
                test: ["./index.js"]
            };
        }

        var all = {};
        if (t && c) {
            var r = getCaseinfo(t, c);
            all[t] = r ? [r] : [];
        } else {
            var types = t ? [t] : util.keys(casesPath);
            types.forEach(function(t) {
                var r = [],
                    list = fs.readdir(path.join(__dirname, casesPath[t]));
                list.forEach(function(f) {
                    if (!fs.stat(path.join(__dirname, casesPath[t] + f)).isDirectory() || ['.', '..'].indexOf(f) > -1) return;
                    var d = getCaseinfo(t, f);
                    if (d) {
                        r.push(d);
                    }
                });
                all[t] = r;
            });
        }
        return all;
    },
    chooseCases: function(data, t) {
        var table = new AsciiTable(t + '-Test');
        table.setHeading(['id', '用例名称', '用例数量']);
        for (var i = 0; i < data.length; i++) {
            var v = data[i];
            table.addRow(i, v.name, v.test.length);
        }
        console.log(table.toString());
    },
    runCases: function(cases) {
        //打开数据库连接-删除数据库
        var conn = db.open("mysql://root:zhang1998\@localhost/mysql");

        global.clearDB = function() {
            // 清理数据库
            try {
                conn.execute("drop database manage_test")
            } catch (e) {

            }
            // 重新初始化
            process.run("go", ["run", "initDatabase.go", "test"])
        };
        clearDB()

        var _fn = function(d) {
            var prefix = casesPath[k] + d.name + '/';
            d.test.forEach(function(c) {
                try
                {
                    requireRoot(prefix + c);
                } catch (e) {
                    console.error(e.stack, prefix + c);
                }
            });
        };

        for (var k in cases) {
            cases[k].forEach(_fn);
        }
        require('test').run(console.DEBUG);
        // 清理数据库
        conn.close();
    }
};

var params = process.argv,
    t = (params[2] || '').toLowerCase(),
    c = (params[3] || '').toLowerCase();

if (t && !casesPath[t]) {
    console.error('[ERROR]支持用例类型:defs!');
    process.exit(-1);
}

var allcases = fn.listCases(t, c === 'all' ? '' : c);
if (t && !c) {
    var data = allcases[t];
    if (!data.length) {
        console.error('[ERROR]类型 %s 暂时没有用例!', t);
        process.exit(-1);
    }
    fn.chooseCases(data, t);
    var d,
        indexs,
        _fn = function(i) {
            var v = data[i];
            if (!v) return false;
            d.push(v);
            return true;
        };
    while (true) {
        indexs = console.readLine('选择用例(支持all):').toLowerCase();
        if (indexs !== 'all') {
            d = [];
            var r = indexs.split(',').every(_fn);
            if (!r) continue;
            allcases[t] = d;
        }
        break;
    }

}

(function shortcuts() {
    global.print = console.error.bind(console);
}());

fn.runCases(allcases);

coroutine.sleep(200);
GC();
console.log(no, os.memoryUsage().nativeObjects.objects);